package org.secangkirkopipanas.gxtcore.server.dao.impl;

import java.util.List;

import org.hibernate.SessionFactory;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.secangkirkopipanas.gxtcore.common.exception.DataNotFoundException;
import org.secangkirkopipanas.gxtcore.server.dao.ISystemGroupDAO;
import org.secangkirkopipanas.gxtcore.server.domain.SystemGroup;
import org.secangkirkopipanas.gxtcore.server.domain.SystemUser;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

public class SystemGroupDAO implements ISystemGroupDAO {

	private SessionFactory sessionFactory;

	public SessionFactory getSessionFactory() {
		return sessionFactory;
	}

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public void add(SystemGroup systemGroup) {
		sessionFactory.getCurrentSession().saveOrUpdate(systemGroup);
	}

	@Transactional(propagation = Propagation.SUPPORTS)
	public SystemGroup get(long systemGroupId) {
		return (SystemGroup) sessionFactory.getCurrentSession().createCriteria(
				SystemGroup.class).add(Restrictions.idEq(systemGroupId))
				.uniqueResult();
	}

	@Transactional(propagation = Propagation.SUPPORTS)
	public SystemGroup get(String systemGroupName) {
		return (SystemGroup) sessionFactory.getCurrentSession().createCriteria(
				SystemGroup.class)
				.add(Restrictions.eq("name", systemGroupName)).uniqueResult();
	}

	@SuppressWarnings("unchecked")
	@Transactional(propagation = Propagation.SUPPORTS)
	public List<SystemGroup> getForList() {
		return sessionFactory.getCurrentSession().createCriteria(
				SystemGroup.class).list();
	}

	@SuppressWarnings("unchecked")
	@Transactional(propagation = Propagation.SUPPORTS)
	public List<SystemUser> getGroupMembers(SystemGroup systemGroup) {
		return sessionFactory.getCurrentSession().createCriteria(
				SystemUser.class).add(Restrictions.eq("group", systemGroup))
				.list();
	}

	@Transactional(propagation = Propagation.SUPPORTS)
	public int getTotalCount() {
		return (Integer) sessionFactory.getCurrentSession().createCriteria(
				SystemGroup.class).setProjection(Projections.rowCount()).list()
				.get(0);
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public void delete(SystemGroup systemGroup) throws DataNotFoundException {
		SystemGroup systemGroupFound = get(systemGroup.getName());
		if (systemGroupFound != null) {
			sessionFactory.getCurrentSession().delete(systemGroup);
		} else {
			throw new DataNotFoundException("Group with name '"
					+ systemGroup.getName() + "' is not found");
		}
	}

	@Transactional(propagation = Propagation.REQUIRED)
	public void delete(String groupName) throws DataNotFoundException {
		SystemGroup systemGroupFound = get(groupName);
		if (systemGroupFound != null) {
			sessionFactory.getCurrentSession().delete(systemGroupFound);
		} else {
			throw new DataNotFoundException("Group with name '" + groupName
					+ "' is not found");
		}
	}

}